#include "UnitTest++/UnitTest++.h"

#include "matrix.h"

TEST(Matrix_Init)
{
    Matrix<int> mat(4,4,12);
    int array[4*4];
    for (int i = 0; i < 16; i++)
        array[i] = 12;
    CHECK_ARRAY_EQUAL(array,mat.data(),4*4);
}

TEST (Matrix_Access)
{
    Matrix<int> mat(4,4,0);
    for (int i = 0; i < 4; ++i)
        for (int j = 0; j < 4; ++j)
            *(mat.at(i,j)) = (i * 10)+j;

    int array[4*4] = {0,1,2,3,
                     10,11,12,13,
                     20,21,22,23,
                     30,31,32,33};
    CHECK_ARRAY_EQUAL(array,mat.data(),4*4);
}

TEST (Matrix_Downsizing)
{
    Matrix<int> mat(4,4,0);
    for (int i = 0; i < 4; ++i)
        for (int j = 0; j < 4; ++j)
            *(mat.at(i,j)) = (i * 10) + j;

    int array[4*4] = {0,1,
                     10,11};

    CHECK_ARRAY_EQUAL(array,mat(2,2).data(),2*2);
}

TEST (Matrix_Add)
{
    Matrix<int> A(4,4,2);
    Matrix<int> B(4,4,2);
    int array[4*4];
    for (int i = 0; i < 16; i++)
        array[i] = 4;
    Matrix<int> C = A + B;
    CHECK_ARRAY_EQUAL(array,C.data(),4*4);
}

TEST (Matrix_Sub)
{
    Matrix<int> A(4,4,6);
    Matrix<int> B(4,4,2);
    int array[4*4];
    for (int i = 0; i < 16; i++)
        array[i] = 4;
    Matrix<int> C = A - B;
    CHECK_ARRAY_EQUAL(array,C.data(),4*4);
}

TEST (Matrix_Copie)
{
    Matrix<int> A(4,4,6);
    Matrix<int> B(A);
    CHECK(A.data() != B.data());
    CHECK(A.width() == B.width());
    CHECK(A.height() == B.height());
    CHECK_ARRAY_EQUAL(A.data(),B.data(),4*4);
}

TEST (Matrix_Affectation)
{
    Matrix<int> A(4,4,6);
    Matrix<int> B = A;
    CHECK(A.data() != B.data());
    CHECK(A.width() == B.width());
    CHECK(A.height() == B.height());
    CHECK_ARRAY_EQUAL(A.data(),B.data(),4*4);
}

TEST (Matrix_Mult)
{
    Matrix<int> A(4,4,6);
    Matrix<int> B(4,4,2);
    Matrix<int> C = A * B;
    int array[4*4];
    for (int i = 0; i < 16; i++)
        array[i] = 48;
    CHECK_ARRAY_EQUAL(array,C.data(),4*4);
}

TEST (Matrix_SelfMult)
{
    Matrix<int> A(4,4,6);
    Matrix<int> B(4,4,2);
    Matrix<int> C = A;
    C *= B;
    int array[4*4];
    for (int i = 0; i < 16; i++)
        array[i] = 48;
    CHECK_ARRAY_EQUAL(array,C.data(),4*4);
}

TEST (Matrix_MultAdd)
{
    Matrix<int> A(4,4,6);
    Matrix<int> B(4,4,2);
    Matrix<int> C(4,4,0);
    Matrix<int>::multiplyAdd(A,B,C);
    int array[4*4];
    for (int i = 0; i < 16; i++)
        array[i] = 48;
    CHECK_ARRAY_EQUAL(array,C.data(),4*4);
}

TEST (Matrix_Stream)
{
    Matrix<int> A(4,4,6);
    Matrix<int> B(4,4,0);
    std::stringstream str;
    str << A;
    str >> B;
    CHECK_ARRAY_EQUAL(A.data(),B.data(),4*4);
}
